Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: upgrade benchmark suite to divan and add phf #8

Closed
wants to merge 4 commits into from

Conversation

beeb
Copy link
Contributor

@beeb beeb commented Sep 24, 2024

I wanted to compare the performance of trie-hard vs phf but the existing benchmark suite was a bit hard to grasp, and the output was not pretty.

I took a bit of time to refactor it using divan and thought it might be a good contribution to the repo. Let me know if it's acceptable or if I need to change anything.

Note that there is no insert benchmark for PHF as it is an immutable data structure generated at compile time.

Ideally, I'd like to have a separate build.rs file for the benchmark suite, but I don't think that's something that cargo supports. I could generate the sets inside the bench and remove the build script entirely but that would need updating any time the text files changes, and would only be practical for the "headers" and "small" cases. Let me know if this is preferable!

Sample output:

Timer precision: 10 ns
bench                 fastest       │ slowest       │ median        │ mean          │ samples │ iters
├─ hashmap_get                      │               │               │               │         │
│  ├─ Big - 001%      1.114 ms      │ 1.526 ms      │ 1.155 ms      │ 1.168 ms      │ 100     │ 100
│  ├─ Big - 002%      1.117 ms      │ 1.26 ms       │ 1.156 ms      │ 1.163 ms      │ 100     │ 100
│  ├─ Big - 005%      1.137 ms      │ 1.805 ms      │ 1.181 ms      │ 1.197 ms      │ 100     │ 100
│  ├─ Big - 010%      1.165 ms      │ 1.32 ms       │ 1.213 ms      │ 1.216 ms      │ 100     │ 100
│  ├─ Big - 025%      1.192 ms      │ 1.433 ms      │ 1.234 ms      │ 1.244 ms      │ 100     │ 100
│  ├─ Big - 050%      1.095 ms      │ 1.593 ms      │ 1.135 ms      │ 1.151 ms      │ 100     │ 100
│  ├─ Big - 075%      1.122 ms      │ 1.403 ms      │ 1.169 ms      │ 1.176 ms      │ 100     │ 100
│  ├─ Big - 100%      1.014 ms      │ 1.29 ms       │ 1.065 ms      │ 1.073 ms      │ 100     │ 100
│  ├─ Header - 001%   1.036 ms      │ 1.209 ms      │ 1.081 ms      │ 1.093 ms      │ 100     │ 100
│  ├─ Header - 002%   1.045 ms      │ 1.422 ms      │ 1.091 ms      │ 1.113 ms      │ 100     │ 100
│  ├─ Header - 005%   1.06 ms       │ 1.228 ms      │ 1.107 ms      │ 1.112 ms      │ 100     │ 100
│  ├─ Header - 010%   1.092 ms      │ 1.304 ms      │ 1.136 ms      │ 1.139 ms      │ 100     │ 100
│  ├─ Header - 025%   1.141 ms      │ 1.254 ms      │ 1.181 ms      │ 1.188 ms      │ 100     │ 100
│  ├─ Header - 050%   1.003 ms      │ 1.443 ms      │ 1.044 ms      │ 1.05 ms       │ 100     │ 100
│  ├─ Header - 075%   901.5 µs      │ 1.06 ms       │ 972.3 µs      │ 973.2 µs      │ 100     │ 100
│  ├─ Header - 100%   656.1 µs      │ 802 µs        │ 680.7 µs      │ 686.1 µs      │ 100     │ 100
│  ├─ Small - 001%    1.048 ms      │ 1.222 ms      │ 1.117 ms      │ 1.12 ms       │ 100     │ 100
│  ├─ Small - 002%    1.057 ms      │ 1.359 ms      │ 1.125 ms      │ 1.133 ms      │ 100     │ 100
│  ├─ Small - 005%    1.074 ms      │ 1.241 ms      │ 1.131 ms      │ 1.136 ms      │ 100     │ 100
│  ├─ Small - 010%    1.091 ms      │ 1.282 ms      │ 1.146 ms      │ 1.155 ms      │ 100     │ 100
│  ├─ Small - 025%    1.072 ms      │ 1.245 ms      │ 1.141 ms      │ 1.147 ms      │ 100     │ 100
│  ├─ Small - 050%    934.8 µs      │ 1.158 ms      │ 992.2 µs      │ 994.7 µs      │ 100     │ 100
│  ├─ Small - 075%    902.8 µs      │ 1.093 ms      │ 936.3 µs      │ 952.9 µs      │ 100     │ 100
│  ╰─ Small - 100%    572.1 µs      │ 638.7 µs      │ 593.5 µs      │ 595.7 µs      │ 100     │ 100
├─ hashmap_insert                   │               │               │               │         │
│  ├─ Big             302.5 µs      │ 412.5 µs      │ 312.7 µs      │ 316.1 µs      │ 100     │ 100
│  ╰─ Small           2.769 µs      │ 3.119 µs      │ 2.884 µs      │ 2.896 µs      │ 100     │ 100
├─ phf_get                          │               │               │               │         │
│  ├─ Big - 001%      1.064 ms      │ 1.413 ms      │ 1.108 ms      │ 1.119 ms      │ 100     │ 100
│  ├─ Big - 002%      1.075 ms      │ 1.518 ms      │ 1.125 ms      │ 1.138 ms      │ 100     │ 100
│  ├─ Big - 005%      1.118 ms      │ 1.767 ms      │ 1.151 ms      │ 1.174 ms      │ 100     │ 100
│  ├─ Big - 010%      1.149 ms      │ 1.501 ms      │ 1.212 ms      │ 1.23 ms       │ 100     │ 100
│  ├─ Big - 025%      1.172 ms      │ 1.356 ms      │ 1.235 ms      │ 1.239 ms      │ 100     │ 100
│  ├─ Big - 050%      1.07 ms       │ 1.419 ms      │ 1.112 ms      │ 1.123 ms      │ 100     │ 100
│  ├─ Big - 075%      1.092 ms      │ 1.523 ms      │ 1.129 ms      │ 1.15 ms       │ 100     │ 100
│  ├─ Big - 100%      945.2 µs      │ 1.306 ms      │ 989.2 µs      │ 1.003 ms      │ 100     │ 100
│  ├─ Header - 001%   996.8 µs      │ 1.248 ms      │ 1.039 ms      │ 1.044 ms      │ 100     │ 100
│  ├─ Header - 002%   1.008 ms      │ 1.245 ms      │ 1.048 ms      │ 1.058 ms      │ 100     │ 100
│  ├─ Header - 005%   1.031 ms      │ 1.363 ms      │ 1.07 ms       │ 1.079 ms      │ 100     │ 100
│  ├─ Header - 010%   1.051 ms      │ 1.369 ms      │ 1.086 ms      │ 1.107 ms      │ 100     │ 100
│  ├─ Header - 025%   1.079 ms      │ 1.529 ms      │ 1.13 ms       │ 1.141 ms      │ 100     │ 100
│  ├─ Header - 050%   951.8 µs      │ 1.278 ms      │ 984.4 µs      │ 989.9 µs      │ 100     │ 100
│  ├─ Header - 075%   846.2 µs      │ 945.6 µs      │ 882 µs        │ 887.2 µs      │ 100     │ 100
│  ├─ Header - 100%   655.3 µs      │ 714.2 µs      │ 679.7 µs      │ 681.6 µs      │ 100     │ 100
│  ├─ Small - 001%    984.8 µs      │ 1.466 ms      │ 1.029 ms      │ 1.036 ms      │ 100     │ 100
│  ├─ Small - 002%    990.5 µs      │ 1.321 ms      │ 1.043 ms      │ 1.05 ms       │ 100     │ 100
│  ├─ Small - 005%    1.003 ms      │ 1.167 ms      │ 1.061 ms      │ 1.066 ms      │ 100     │ 100
│  ├─ Small - 010%    1.018 ms      │ 1.411 ms      │ 1.059 ms      │ 1.071 ms      │ 100     │ 100
│  ├─ Small - 025%    1.005 ms      │ 1.714 ms      │ 1.039 ms      │ 1.049 ms      │ 100     │ 100
│  ├─ Small - 050%    879.8 µs      │ 1.245 ms      │ 912.8 µs      │ 927.3 µs      │ 100     │ 100
│  ├─ Small - 075%    806.4 µs      │ 1.145 ms      │ 848.6 µs      │ 856.6 µs      │ 100     │ 100
│  ╰─ Small - 100%    578.4 µs      │ 633.4 µs      │ 593.9 µs      │ 597.2 µs      │ 100     │ 100
├─ radix_trie_get                   │               │               │               │         │
│  ├─ Big - 001%      2.924 ms      │ 4.393 ms      │ 3.055 ms      │ 3.16 ms       │ 100     │ 100
│  ├─ Big - 002%      3.012 ms      │ 4.249 ms      │ 3.11 ms       │ 3.149 ms      │ 100     │ 100
│  ├─ Big - 005%      3.153 ms      │ 4.642 ms      │ 3.324 ms      │ 3.369 ms      │ 100     │ 100
│  ├─ Big - 010%      3.376 ms      │ 5.003 ms      │ 3.545 ms      │ 3.609 ms      │ 100     │ 100
│  ├─ Big - 025%      4.111 ms      │ 5.227 ms      │ 4.234 ms      │ 4.284 ms      │ 100     │ 100
│  ├─ Big - 050%      5.053 ms      │ 6.628 ms      │ 5.25 ms       │ 5.299 ms      │ 100     │ 100
│  ├─ Big - 075%      6.031 ms      │ 9.098 ms      │ 6.308 ms      │ 6.429 ms      │ 100     │ 100
│  ├─ Big - 100%      6.839 ms      │ 9.386 ms      │ 7.107 ms      │ 7.163 ms      │ 100     │ 100
│  ├─ Header - 001%   1.69 ms       │ 2.061 ms      │ 1.74 ms       │ 1.752 ms      │ 100     │ 100
│  ├─ Header - 002%   1.7 ms        │ 2.165 ms      │ 1.773 ms      │ 1.781 ms      │ 100     │ 100
│  ├─ Header - 005%   1.794 ms      │ 2.364 ms      │ 1.875 ms      │ 1.895 ms      │ 100     │ 100
│  ├─ Header - 010%   1.911 ms      │ 2.45 ms       │ 2.012 ms      │ 2.016 ms      │ 100     │ 100
│  ├─ Header - 025%   2.26 ms       │ 2.549 ms      │ 2.36 ms       │ 2.357 ms      │ 100     │ 100
│  ├─ Header - 050%   2.754 ms      │ 3.054 ms      │ 2.852 ms      │ 2.858 ms      │ 100     │ 100
│  ├─ Header - 075%   3.161 ms      │ 3.582 ms      │ 3.292 ms      │ 3.289 ms      │ 100     │ 100
│  ├─ Header - 100%   3.305 ms      │ 3.724 ms      │ 3.557 ms      │ 3.552 ms      │ 100     │ 100
│  ├─ Small - 001%    1.817 ms      │ 2.005 ms      │ 1.887 ms      │ 1.888 ms      │ 100     │ 100
│  ├─ Small - 002%    1.83 ms       │ 2.086 ms      │ 1.905 ms      │ 1.908 ms      │ 100     │ 100
│  ├─ Small - 005%    1.884 ms      │ 2.117 ms      │ 1.958 ms      │ 1.958 ms      │ 100     │ 100
│  ├─ Small - 010%    1.928 ms      │ 2.562 ms      │ 2.016 ms      │ 2.022 ms      │ 100     │ 100
│  ├─ Small - 025%    2.076 ms      │ 2.83 ms       │ 2.144 ms      │ 2.155 ms      │ 100     │ 100
│  ├─ Small - 050%    2.137 ms      │ 2.494 ms      │ 2.228 ms      │ 2.235 ms      │ 100     │ 100
│  ├─ Small - 075%    2.167 ms      │ 2.401 ms      │ 2.266 ms      │ 2.264 ms      │ 100     │ 100
│  ╰─ Small - 100%    1.746 ms      │ 2.178 ms      │ 1.891 ms      │ 1.905 ms      │ 100     │ 100
├─ radix_trie_insert                │               │               │               │         │
│  ├─ Big             2.152 ms      │ 2.518 ms      │ 2.226 ms      │ 2.235 ms      │ 100     │ 100
│  ╰─ Small           14.63 µs      │ 31.17 µs      │ 15.24 µs      │ 15.71 µs      │ 100     │ 100
├─ trie_get                         │               │               │               │         │
│  ├─ Big - 001%      620.8 µs      │ 779.1 µs      │ 642.1 µs      │ 657 µs        │ 100     │ 100
│  ├─ Big - 002%      667.7 µs      │ 942.4 µs      │ 690.5 µs      │ 712.5 µs      │ 100     │ 100
│  ├─ Big - 005%      814.3 µs      │ 1.683 ms      │ 838.6 µs      │ 864.7 µs      │ 100     │ 100
│  ├─ Big - 010%      1.005 ms      │ 2.12 ms       │ 1.055 ms      │ 1.096 ms      │ 100     │ 100
│  ├─ Big - 025%      1.47 ms       │ 2.889 ms      │ 1.543 ms      │ 1.578 ms      │ 100     │ 100
│  ├─ Big - 050%      2.239 ms      │ 3.294 ms      │ 2.323 ms      │ 2.369 ms      │ 100     │ 100
│  ├─ Big - 075%      3.064 ms      │ 3.923 ms      │ 3.215 ms      │ 3.254 ms      │ 100     │ 100
│  ├─ Big - 100%      3.732 ms      │ 5.136 ms      │ 3.934 ms      │ 3.953 ms      │ 100     │ 100
│  ├─ Header - 001%   430.7 µs      │ 538.9 µs      │ 475.5 µs      │ 474.7 µs      │ 100     │ 100
│  ├─ Header - 002%   459 µs        │ 977 µs        │ 496.7 µs      │ 503.6 µs      │ 100     │ 100
│  ├─ Header - 005%   525.6 µs      │ 682.4 µs      │ 558.5 µs      │ 567.7 µs      │ 100     │ 100
│  ├─ Header - 010%   605 µs        │ 729 µs        │ 649 µs        │ 649.5 µs      │ 100     │ 100
│  ├─ Header - 025%   794.7 µs      │ 1.422 ms      │ 852.3 µs      │ 863.5 µs      │ 100     │ 100
│  ├─ Header - 050%   957.8 µs      │ 1.315 ms      │ 1.019 ms      │ 1.041 ms      │ 100     │ 100
│  ├─ Header - 075%   1.092 ms      │ 1.236 ms      │ 1.148 ms      │ 1.152 ms      │ 100     │ 100
│  ├─ Header - 100%   1.183 ms      │ 1.539 ms      │ 1.231 ms      │ 1.248 ms      │ 100     │ 100
│  ├─ Small - 001%    389.1 µs      │ 640.5 µs      │ 406.9 µs      │ 417.1 µs      │ 100     │ 100
│  ├─ Small - 002%    404.9 µs      │ 592 µs        │ 415.9 µs      │ 425.5 µs      │ 100     │ 100
│  ├─ Small - 005%    437.1 µs      │ 1.032 ms      │ 447.2 µs      │ 469.2 µs      │ 100     │ 100
│  ├─ Small - 010%    476.6 µs      │ 624.5 µs      │ 496.2 µs      │ 507 µs        │ 100     │ 100
│  ├─ Small - 025%    512.7 µs      │ 703.4 µs      │ 528.5 µs      │ 545.1 µs      │ 100     │ 100
│  ├─ Small - 050%    531.6 µs      │ 682.2 µs      │ 558.7 µs      │ 565.1 µs      │ 100     │ 100
│  ├─ Small - 075%    528.1 µs      │ 847.4 µs      │ 555.2 µs      │ 567.4 µs      │ 100     │ 100
│  ╰─ Small - 100%    460.1 µs      │ 599.2 µs      │ 477.4 µs      │ 484.8 µs      │ 100     │ 100
╰─ trie_insert                      │               │               │               │         │
   ├─ Big             7.002 ms      │ 9.571 ms      │ 7.173 ms      │ 7.199 ms      │ 100     │ 100
   ╰─ Small           49.37 µs      │ 158.3 µs      │ 51.74 µs      │ 54.07 µs      │ 100     │ 100

let mut big_set = phf_codegen::Set::<&str>::new();
const OW_1984: &str = include_str!("data/1984.txt");
for s in OW_1984
.split(|c: char| c.is_whitespace())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good catch. I didn't even thing about there being line breaks in the file. Duh

@johnhurt
Copy link
Collaborator

This is beautiful! I have never heard of divan, but the output is so much easier to read than criterion's. It doesn't look like it supports the regression-tracking features that criterion, but that might be a small price to pay for all the improvements here. 😅

I am going to mark this pr Accepted. What happens next is:

  1. It will get ingested into our internal copy of this repo
  2. Once it's approved and merged there
  3. Your contributions will show up here as a single, squashed commit attributed to you in our weekly(ish) sync
  4. I'll close this pr
  5. You receive heaped praise from the community

Thanks!

@johnhurt johnhurt added the Accepted PR has been ingested and is waiting internal approval label Sep 24, 2024
}
}

fn args() -> impl Iterator<Item = Input> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so much cleaner than the nasty, macro cartesian product I was doing before. 👏

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback! 🫶

@johnhurt
Copy link
Collaborator

I like your suggestion of having this run in a build.rs or some other automated way. I don't have any good solutions for that either, but fwiw, the text files aren't likely to change.

@beeb
Copy link
Contributor Author

beeb commented Sep 25, 2024

I like your suggestion of having this run in a build.rs or some other automated way. I don't have any good solutions for that either, but fwiw, the text files aren't likely to change.

The downside of the build.rs file is that is gets ran on any machine that compiles the library, which is useless in most cases. I could see this as not being acceptable so let me know if I create the sets statically inside the benchmark file ;)

@beeb
Copy link
Contributor Author

beeb commented Sep 26, 2024

Could it be an option to add the build.rs to the exclude field of Cargo.toml so it doesn't get packaged when distributing?

@johnhurt
Copy link
Collaborator

We're probably over thinking it. If we had a script that ran the benchmarks and wrote them to a file, we could run that manually in our weekly syncs.

We can add an automatic bench marker later if there's a bigger need.

@beeb
Copy link
Contributor Author

beeb commented Sep 29, 2024

@johnhurt do you suggest I use this model instead then? https://github.com/beeb/trie-hard/blob/divan-bench-nobuild/benches/bench.rs

This would remove the build.rs for now and we have the option to automate later.

johnhurt pushed a commit that referenced this pull request Oct 4, 2024
---
chore: split on lines instead of whitespace
---
chore: sort deps
---
chore: fix phf bench

Includes-commit: 0158c61
Includes-commit: 7e4b9f3
Includes-commit: 87927a5
Includes-commit: 9ef8366
Replicated-from: #8
johnhurt pushed a commit that referenced this pull request Oct 7, 2024
---
chore: split on lines instead of whitespace
---
chore: sort deps
---
chore: fix phf bench

Includes-commit: 0158c61
Includes-commit: 7e4b9f3
Includes-commit: 87927a5
Includes-commit: 9ef8366
Replicated-from: #8
@johnhurt
Copy link
Collaborator

johnhurt commented Oct 7, 2024

I just merged this into the main branch as part of our weekly sync. Thanks again! I will work on putting in a way to run and publish the benchmarks when we publish ... maybe with some more charts 😂

@johnhurt johnhurt closed this Oct 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Accepted PR has been ingested and is waiting internal approval
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants